﻿using Microsoft.Extensions.DependencyInjection;
using SD.IdentitySystem.IAppService.Interfaces;
using SD.Infrastructure.Constants;
using SD.Infrastructure.MemberShip;
using SD.IOC.Core.Mediators;
using SD.IOC.Extension.NetFx;
using SD.OpcProxy.IAppService.DTOs.Outputs;
using SD.OpcProxy.IAppService.Interfaces;
using SD.OpcProxy.InitializationTool.Models;
using SD.OpcProxy.ValueObjects.Enums;
using SD.Toolkits.Excel;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SD.OpcProxy.InitializationTool
{
    class Program
    {
        /// <summary>
        /// 数据源路径
        /// </summary>
        private const string DataSourcePath = "DataSource.xls";

        /// <summary>
        /// 身份认证服务接口
        /// </summary>
        private static IAuthenticationContract _AuthenticationContract;

        /// <summary>
        /// OPC代理服务接口
        /// </summary>
        private static IOpcProxyContract _OpcProxyContract;

        /// <summary>
        /// 程序主入口
        /// </summary>
        static void Main()
        {
            //初始化依赖注入容器
            InitContainer();

            _AuthenticationContract = ResolveMediator.Resolve<IAuthenticationContract>();
            _OpcProxyContract = ResolveMediator.Resolve<IOpcProxyContract>();

            //登录
            Console.WriteLine("正在登录...");
            Login();
            Console.WriteLine("登录成功！");
            Console.WriteLine("-------------------");

            //导入OPC服务器
            Console.WriteLine("正在导入OPC服务器...");
            ImportOpcServers();
            Console.WriteLine("导入OPC服务器完成！");
            Console.WriteLine("-------------------");

            //导入变量
            Console.WriteLine("正在导入变量...");
            ImportVariables();
            Console.WriteLine("导入变量完成！");
            Console.WriteLine("-------------------");

            Console.WriteLine("程序结束！");
            Console.ReadKey();
        }

        /// <summary>
        /// 初始化依赖注入容器
        /// </summary>
        static void InitContainer()
        {
            if (!ResolveMediator.ContainerBuilt)
            {
                IServiceCollection builder = ResolveMediator.GetServiceCollection();
                builder.RegisterConfigs();
                ResolveMediator.Build();
            }
        }

        /// <summary>
        /// 登录
        /// </summary>
        static void Login()
        {
            LoginInfo loginInfo = _AuthenticationContract.Login(CommonConstants.AdminLoginId, CommonConstants.InitialPassword);
            AppDomain.CurrentDomain.SetData(SessionKey.CurrentUser, loginInfo);
        }

        /// <summary>
        /// 导入OPC服务器
        /// </summary>
        static void ImportOpcServers()
        {
            OpcServerModel[] opcServerModels = ExcelReader.ReadFile<OpcServerModel>(DataSourcePath, "OPC服务器");
            foreach (OpcServerModel model in opcServerModels)
            {
                OpcMode opcMode = model.OPC模式 == OpcMode.DA.ToString() ? OpcMode.DA : OpcMode.UA;
                _OpcProxyContract.CreateOpcServer(model.服务器名称, opcMode, model.服务器地址, model.Ping间隔, model.监听间隔, model.超时时间);
            }
        }

        /// <summary>
        /// 导入变量
        /// </summary>
        static void ImportVariables()
        {
            VariableModel[] variableModels = ExcelReader.ReadFile<VariableModel>(DataSourcePath, "变量");
            IDictionary<string, Dictionary<string, string>> variableValueDescriptionGroups = ExcelReader.ReadFile<VariableValueDescriptionModel>(DataSourcePath, "变量值描述").GroupBy(x => x.变量编号).ToDictionary(x => x.Key, x => x.ToDictionary(y => y.变量值, y => y.变量值描述));

            IDictionary<string, OpcServerInfo> opcServerInfos = _OpcProxyContract.GetOpcServersByPage(null, 1, int.MaxValue).Datas.ToDictionary(x => x.Number, x => x);

            foreach (VariableModel variableModel in variableModels)
            {
                IDictionary<string, string> valueDescriptions = null;

                if (variableValueDescriptionGroups.ContainsKey(variableModel.变量编号))
                {
                    valueDescriptions = variableValueDescriptionGroups[variableModel.变量编号];
                }

                OpcServerInfo opcServerInfo = opcServerInfos[variableModel.OPC服务器URL];

                VariableType variableType = variableModel.变量类型 == "外部变量" ? VariableType.External : VariableType.Internal;
                string unit = variableModel.单位 == "NULL" ? null : variableModel.单位;

                _OpcProxyContract.CreateVariable(variableModel.变量编号, variableModel.变量名称, variableType, variableModel.是否只读, variableModel.数据类型, opcServerInfo.Id, unit, variableModel.是否记录历史, variableModel.变量名称, valueDescriptions);
            }
        }
    }
}
